﻿


MainClass = function () {
    var self = this;

    function Global() {
        this.Identity = 1;
        this.NewID = function () {
            return this.Identity++;
        };
    }
    var G = new Global();
    var SEARCH_URL = "/search/",
        TAG_CLOUD_TOKEN = "/TagCloud",
        lockHistoryChange = false;
    Ext.selection.TreeModel.prototype.onKeyUp = Ext.Function.createInterceptor(Ext.selection.TreeModel.prototype.onKeyUp, function () {
        var store = this.store,
            idx = store.indexOf(this.lastFocused),
            visIdx,
            record,
            focusSearchField;

        if (idx === 0) {
            focusSearchField = true;
        } else {
            record = store.getAt(idx - 1);
            visIdx = idx - 1;

            while (visIdx > 0 && record.data.hidden) {
                record = store.getAt(--visIdx);
            }

            if (record.data.hidden) {
                focusSearchField = true;
            }
        }

        if (focusSearchField) {
            this.deselectAll();
            App.SearchField.focus(false, 100);
        }
    });


    var makeTab = function (id, url, title) {
        var
            tab,
            hostName,
            node,
            tabTip;

        if (id === "-") {
            id = Ext.id(undefined, "extnet");
            lookup[url] = id;
        }

        tabTip = url.replace(/^\//g, "");
        tabTip = tabTip.replace(/\/$/g, "");
        tabTip = tabTip.replace(/\//g, " > ");
        tabTip = tabTip.replace(/_/g, " ");


        hostName = window.location.protocol + "//" + window.location.host;

        var newId = G.NewID();
        tab = App.ExampleTabs.add(new Ext.panel.Panel({
            id: "ExampleTabs_Panel" + newId,
            title: title,
            tabTip: tabTip,
            layout: "fit",
            hideMode: "offsets",
            loader: {
                scripts: true,//extjs 5 以后这个属性不起作用
                autoLoad: true,
                renderer: function (loader, response, active) {
                    loader.getTarget().update(response.responseText, true);
                    return true;
                },
                url: hostName + url,
                params: { "containerId": "ExampleTabs_Panel" + newId },
                failure: function () { alert("加载错误"); },
                listeners: {
                    beforeload: function () {
                        this.target.body.mask('正在加载...');
                    },
                    load: function (loader) {
                        if (this.target.body)
                            this.target.body.unmask();
                    }
                }
            },
            closable: true
        }));

        setTimeout(function () {
            App.ExampleTabs.setActiveTab(tab);
        }, 250);

        var node = App.exampleTree.getStore().getNodeById(id),
            expandAndSelect = function (node) {
                var view = App.exampleTree.getView(),
                    originalAnimate = view.animate;

                view.animate = false;
                node.bubble(function (node) {
                    node.expand(false);
                });

                App.exampleTree.getSelectionModel().select(node);
                view.animate = originalAnimate;
            };

        if (node) {
            expandAndSelect(node);
        } else {
            App.exampleTree.on("load", function (node) {
                node = App.exampleTree.getStore().getNodeById(id);
                if (node) {
                    expandAndSelect(node);
                }
            }, this, { delay: 10, single: true });
        }
    };

    var lookup = {};

    self.onTreeAfterRender = function (tree) {
        var sm = tree.getSelectionModel();

        Ext.create('Ext.util.KeyNav', tree.view.el, {
            enter: function (e) {
                if (sm.hasSelection()) {
                    self.onTreeItemClick(sm.getSelection()[0], e);
                }
            }
        });
    };

    self.onTreeItemClick = function (record, e) {
        if (record.isLeaf()) {
            e.stopEvent();
            self.loadExample(record.get('route'), record.getId(), record.get('text'));
        } else {
            record[record.isExpanded() ? 'collapse' : 'expand']();
        }
    };

    self.treeRenderer = function (value, metadata, record) {
        if (record.data.isNew) {
            value += "<span>&nbsp;</span>";
        }

        return value;
    };

    self.loadExample = function (href, id, title) {
        var tab = App.ExampleTabs.getComponent(id),
            lObj = lookup[href];
        if (id == "-") {
            App.direct.GetHashCode(href, {
                success: function (result) {
                    self.loadExample(href, "e" + result, title);
                }
            });

            return;
        }

        lookup[href] = id;

        if (tab) {
            App.ExampleTabs.setActiveTab(tab);
        } else {
            if (Ext.isEmpty(title)) {
                var m = /(\w+)\/$/g.exec(href);
                title = m == null ? "[No name]" : m[1];
            }

            title = title.replace(/<span>&nbsp;<\/span>/g, "");
            title = title.replace(/_/g, " ");
            makeTab(id, href, title);
        }
    };

    var viewClick = function (dv, e) {
        var group = e.getTarget("h2", 3, true);

        if (group) {
            group.up("div").toggleClass("collapsed");
        }
    };

    var beforeSourceShow = function (el) {
        var height = Ext.getBody().getViewSize().height;

        if (el.getSize().height > height) {
            el.setHeight(height - 20);
        }
    };

    var change = function (token) {
        if (!lockHistoryChange) {
            if (token) {
                if (token.indexOf(SEARCH_URL) === 0) {
                    filterByUrl(token);
                } else if (token === TAG_CLOUD_TOKEN) {
                    showTagCloud();
                } else {
                    loadExample(token, lookup[token] || "-");
                }
            } else {
                App.ExampleTabs.setActiveTab(0);
            }
        }
        lockHistoryChange = false;
    };

    var getToken = function (url) {
        var host = window.location.protocol + "//" + window.location.host;

        return url.substr(host.length);
    };

    var addToken = function (el, tab) {
        if (tab.loader && tab.loader.url) {
            var token = getToken(tab.loader.url);

            Ext.History.add(token);
        } else if (tab.historyToken) {
            Ext.History.add(tab.historyToken);
        } else {
            Ext.History.add("");
        }
    };

    var keyUp = function (field, e) {
        if (e.getKey() === 40) {
            return;
        }

        if (e.getKey() === Ext.EventObject.ESC) {
            clearFilter(field);
        } else {
            changeFilterHash(field.getRawValue().replace(" ", "+"));
            filter(field);
        }
    };

    var keyUp = function (field, e) {
        if (e.getKey() === 40) {
            return;
        }

        if (e.getKey() === Ext.EventObject.ESC) {
            clearFilter(field);
        } else {
            changeFilterHash(field.getRawValue().replace(" ", "+"));
            filter(field);
        }
    };

    /*
        field: the search field
        byTagsOnly: true means searcing by tags only and by full matching
    */
    var filter = function (field, byTagsOnly) {
        var tree = App.exampleTree,
            text = field.getRawValue(),
            view = tree.getView(),
            originalAnimate = view.animate;

        if (Ext.isEmpty(text, false)) {
            clearFilter(field);
        }

        if (text.length < 2) {
            return;
        }

        if (Ext.isEmpty(text, false)) {
            return;
        }

        field.getTrigger(0).show();

        var re = new RegExp(".*" + text + ".*", "i");

        tree.clearFilter(true);

        tree.filterBy(function (node) {
            var tags = node.data.tags,
                hasTags = Ext.isArray(node.data.tags) && node.data.tags.length > 0,
                match = false,
                pn = node.parentNode,
                i, len,
                tagMatch = false;

            if (App.SearchByTitles.checked && !byTagsOnly) {
                match = re.test(node.data.text);
            }

            if ((App.SearchByTags.checked || byTagsOnly) && hasTags) {
                if (byTagsOnly) {
                    match = match || Ext.Array.contains(tags, text);
                } else {
                    for (i = 0, len = tags.length; i < len; i++) {
                        if (re.test(tags[i])) {
                            match = true;
                            break;
                        }
                    }
                }
            }

            if (match && node.isLeaf()) {
                pn.hasMatchNode = true;
            }

            if (pn != null && pn.fixed) {
                if (node.isLeaf() === false) {
                    node.fixed = true;
                }
                return true;
            }

            if (node.isLeaf() === false) {
                node.fixed = match;
                return match;
            }

            return (pn != null && pn.fixed) || match;
        }, { expandNodes: false });

        view.animate = false;
        tree.getRootNode().cascadeBy(function (node) {
            if (node.isRoot()) {
                return;
            }

            if ((node.getDepth() === 1) ||
                (node.getDepth() === 2 && node.hasMatchNode)) {
                node.expand(false);
            }

            delete node.fixed;
            delete node.hasMatchNode;
        }, tree);

        view.animate = originalAnimate;
    };

    var filterByUrl = function (url) {
        var field = App.SearchField,
            tree = App.exampleTree;

        if (!lockHistoryChange) {
            var tree = App.exampleTree,
                store = tree.getStore(),
                fn = function () {
                    field.setValue(url.substr(SEARCH_URL.length).replace("+", " "));
                    filter(field);
                };

            if (store.loading) {
                store.on("load", fn, null, { single: true, delay: 100 });
            } else {
                fn();
            }
        }
    };

    var clearFilter = function (field, trigger, index, e) {
        var tree = App.exampleTree;

        field.setValue("");
        changeFilterHash("");
        field.getTrigger(0).hide();
        tree.clearFilter(true);
        field.focus(false, 100);
    };

    var changeFilterHash = Ext.Function.createBuffered(
        function (text) {
            lockHistoryChange = true;
            if (text.length > 2) {
                window.location.hash = SEARCH_URL + text;
            } else {
                var tab = App.ExampleTabs.getActiveTab(),
                    token = "";

                if (tab.loader && tab.loader.url) {
                    token = getToken(tab.loader.url);
                }

                Ext.History.add(token);
            }
        },
        500);

    var filterSpecialKey = function (field, e) {
        var tree = App.exampleTree,
            view = tree.getView();

        if (e.getKey() === e.DOWN) {
            var n = tree.getRootNode().findChildBy(function (node) {
                return node.isLeaf() && !node.data.hidden;
            }, tree, true);

            if (n) {
                tree.expandPath(n.getPath(), null, null, function () {
                    tree.getSelectionModel().select(n);
                    view.focusRow(n);
                });
            }
        }
    };


    var swapThemeClass = function (frame, oldTheme, newTheme) {
        var html = Ext.fly(frame.document.body.parentNode);

        html.removeCls('x-theme-' + oldTheme);
        html.addCls('x-theme-' + newTheme);
    };

    var themeChange = function (menu, menuItem) {
        var reload = menuItem.text == "Neptune" || Ext.net.ResourceMgr.theme == "neptune";

        App.direct.GetThemeUrl(menuItem.text, reload, {
            success: function (result) {
                var v = menu.up('viewport'),
                    oldTheme = Ext.net.ResourceMgr.theme,
                    html,
                    frame;

                Ext.net.ResourceMgr.setTheme(result, menuItem.text.toLowerCase());
                Ext.defer(v.doLayout, 500, v);
                App.ExampleTabs.items.each(function (el) {
                    if (!Ext.isEmpty(el.iframe)) {
                        frame = el.getBody();
                        if (frame.Ext) {
                            frame.Ext.net.ResourceMgr.setTheme(result, menuItem.text.toLowerCase());
                        } else {
                            swapThemeClass(frame, oldTheme, Ext.net.ResourceMgr.theme);
                        }
                    }
                });
            }
        });
    };


    if (window.location.href.indexOf("#") > 0) {
        var directLink = window.location.href.substr(window.location.href.indexOf("#") + 1)
                        .replace(/(\s|\<|&lt;|%22|%3C|\"|\'|&quot|&#039;|script)/gi, '');

        Ext.onReady(function () {
            Ext.Function.defer(function () {
                if (directLink.indexOf(SEARCH_URL) === 0) {
                    filterByUrl(directLink);
                } else {
                    if (!Ext.isEmpty(directLink, false)) {
                        if (directLink === TAG_CLOUD_TOKEN) {
                            if (App.exampleTree.store.loading) {
                                App.exampleTree.store.on("load", function () {
                                    showTagCloud();
                                }, null, { single: true });
                            } else {
                                showTagCloud();
                            }
                        } else {
                            loadExample(directLink, "-");
                        }
                    }
                }
            }, 100, window);
        }, window);
    }
}
